﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DbFrame.SqlContext
{
    using System.Data;
    using System.Linq.Expressions;
    using DbFrame.Class;
    using DbFrame.Ado;
    using DbFrame.SqlContext.Abstract;
    using DbFrame.SqlContext.Interface;

    public class FindContext : AbstractFind
    {

        public FindContext(string ConnectionString, DataBaseType DataBaseType) : base(ConnectionString, DataBaseType) { }

        public IQuery<T1> Query<T1>(Expression<Func<T1, object>> Select)
            where T1 : BaseEntity, new()
        {
            return new QueryContext<T1>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2> Query<T1, T2>(Expression<Func<T1, T2, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity, new()
        {
            return new QueryContext<T1, T2>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3> Query<T1, T2, T3>(Expression<Func<T1, T2, T3, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4> Query<T1, T2, T3, T4>(Expression<Func<T1, T2, T3, T4, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5> Query<T1, T2, T3, T4, T5>(Expression<Func<T1, T2, T3, T4, T5, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6> Query<T1, T2, T3, T4, T5, T6>(Expression<Func<T1, T2, T3, T4, T5, T6, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7> Query<T1, T2, T3, T4, T5, T6, T7>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8> Query<T1, T2, T3, T4, T5, T6, T7, T8>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity
            where T11 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity
            where T11 : BaseEntity
            where T12 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity
            where T11 : BaseEntity
            where T12 : BaseEntity
            where T13 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity
            where T11 : BaseEntity
            where T12 : BaseEntity
            where T13 : BaseEntity
            where T14 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(_ConnectionString, _DataBaseType).Select(Select);
        }

        public IQuery<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Query<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, object>> Select)
            where T1 : BaseEntity
            where T2 : BaseEntity
            where T3 : BaseEntity
            where T4 : BaseEntity
            where T5 : BaseEntity
            where T6 : BaseEntity
            where T7 : BaseEntity
            where T8 : BaseEntity
            where T9 : BaseEntity
            where T10 : BaseEntity
            where T11 : BaseEntity
            where T12 : BaseEntity
            where T13 : BaseEntity
            where T14 : BaseEntity
            where T15 : BaseEntity, new()
        {
            return new QueryContext<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(_ConnectionString, _DataBaseType).Select(Select);
        }


















        /************************* 基础 函数***************************/
        public override DataTable FindTableBySql(string SqlStr, object Param)
        {
            return this._DbHelper.Query(SqlStr, Param);
        }

        public override T FindSingleBySql<T>(string SqlStr, object Param)
        {
            return this._DbHelper.QuerySingleOrDefault<T>(SqlStr, Param);
        }

        public override T FindBySql<T>(string SqlStr, object Param)
        {
            var _Model = this._DbHelper.QueryFirstOrDefault<T>(SqlStr, Param);
            if (_Model == null)
                return ReflexHelper.CreateInstance<T>();
            return _Model;
        }

        public override IEnumerable<T> FindListBySql<T>(string SqlStr, object Param)
        {
            return this._DbHelper.Query<T>(SqlStr, Param);
        }

        public override DataTable FindPaging(string Sql, int Page, int PageSize, out int Total, object Param)
        {
            return this._DbHelper.FindPaging(Sql, Page, PageSize, out Total, Param);
        }

        public override int FindMaxNumber(string TabName, string FieldNum, string Where, object Param)
        {
            var SqlStr = "";
            switch (_DataBaseType)
            {
                case DataBaseType.SqlServer:
                    SqlStr = @"SELECT ISNULL(MAX(CONVERT(INT," + FieldNum + ")),0) FROM " + TabName + " WHERE 1=1 " + Where;
                    break;
                case DataBaseType.MySql:
                    SqlStr = @"SELECT IFNULL(MAX(CONVERT(INT," + FieldNum + ")),0) FROM " + TabName + " WHERE 1=1 " + Where;
                    break;
                case DataBaseType.Oracle:
                    SqlStr = @"SELECT ISNULL(MAX(to_number('" + FieldNum + "')),0) FROM " + TabName + " WHERE 1=1 " + Where;
                    break;
                default:
                    break;
            }
            return this.FindSingleBySql<int>(SqlStr, Param);
        }



        /************************* 表达式树 函数***************************/
        public override DataTable FindTable<T>(Expression<Func<T, bool>> Where, Expression<Func<T, object>> OrderBy)
        {
            var _SQL = this.GetSqlStr(null, Where, OrderBy);
            return this._DbHelper.Query(_SQL.Sql_Parameter, _SQL.Parameter);
        }

        public override T Find<T>(Expression<Func<T, bool>> Where)
        {
            var _SQL = this.GetSqlStr(null, Where, null);
            var _Model = this._DbHelper.QueryFirstOrDefault<T>(_SQL.Sql_Parameter, _SQL.Parameter);
            if (_Model == null)
                return ReflexHelper.CreateInstance<T>();
            return _Model;
        }

        public override IEnumerable<T> FindList<T>(Expression<Func<T, bool>> Where, Expression<Func<T, object>> OrderBy)
        {
            var _SQL = this.GetSqlStr(null, Where, OrderBy);
            return this._DbHelper.Query<T>(_SQL.Sql_Parameter, _SQL.Parameter);
        }



        /************************* 表达式树 函数 自定义 Select ***************************/
        public override DataTable FindTable<T>(Expression<Func<T, object>> Select, Expression<Func<T, bool>> Where, Expression<Func<T, object>> OrderBy)
        {
            var _SQL = this.GetSqlStr(Select, Where, OrderBy);
            return this._DbHelper.Query(_SQL.Sql_Parameter, _SQL.Parameter);
        }

        public override T FindSingle<T, W>(Expression<Func<W, object>> Select, Expression<Func<W, bool>> Where)
        {
            var _SQL = this.GetSqlStr(Select, Where, null);
            return this._DbHelper.QuerySingleOrDefault<T>(_SQL.Sql_Parameter, _SQL.Parameter);
        }

        public override T FindSingle<T, W>(string Select, Expression<Func<W, bool>> Where)
        {
            var _SQL = this.GetSqlStr(Select, Where);
            return this._DbHelper.QuerySingleOrDefault<T>(_SQL.Sql_Parameter, _SQL.Parameter);
        }

        public override T Find<T>(Expression<Func<T, object>> Select, Expression<Func<T, bool>> Where)
        {
            var _SQL = this.GetSqlStr(Select, Where, null);
            var _Model = this._DbHelper.QueryFirstOrDefault<T>(_SQL.Sql_Parameter, _SQL.Parameter);
            if (_Model == null)
                return ReflexHelper.CreateInstance<T>();
            return _Model;
        }

        public override IEnumerable<T> FindList<T>(Expression<Func<T, object>> Select, Expression<Func<T, bool>> Where, Expression<Func<T, object>> OrderBy)
        {
            var _SQL = this.GetSqlStr(Select, Where, OrderBy);
            return this._DbHelper.Query<T>(_SQL.Sql_Parameter, _SQL.Parameter);
        }











    }
}
